
package com.joysuch.wwyt.core.service;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.Resource;

import com.joysuch.wwyt.core.bean.FileConvertResult;
import com.joysuch.wwyt.core.entity.BaseAttachmentRepo;
import com.joysuch.wwyt.core.enums.FileConvertStates;
import com.joysuch.wwyt.core.repository.BaseAttachmentRepoDao;
import com.joysuch.wwyt.core.service.impl.JodOfficeToPdfFileConvertor;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class FileConvertService {

    private static final Logger logger = LoggerFactory.getLogger(FileConvertService.class);

    @Autowired
    private BaseAttachmentRepoDao attachmentRepoDao;
    @Autowired
    private BaseImageRepositoryService imageRepoService;
    @Resource(type = JodOfficeToPdfFileConvertor.class)
    private FileConvertor officeFileConvertor;
    private ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    public void convert(BaseAttachmentRepo attachment, File file) {
        String extension = FilenameUtils.getExtension(file.getName());
        if (officeFileConvertor.supportFormat(extension, "pdf")) {
            attachment.setNeedConvert("Y");
            submitConvertTask(officeFileConvertor, attachment, file, "pdf");
        } else if (ifVideo(extension)) {
            attachment.setNeedConvert("Y");
            attachmentRepoDao.save(attachment);
        } else {
            attachment.setNeedConvert("N");
            attachment.setConvertState(FileConvertStates.DO_NOT_SUPPORT.getCode());
            attachmentRepoDao.save(attachment);
        }
    }

    private boolean ifVideo(String extension) {
        return "mp4".equals(extension) || "avi".equals(extension)||"mp3".equals(extension)||"wav".equals(extension);
    }

    private void submitConvertTask(FileConvertor fileConvertor, BaseAttachmentRepo attachment, File file,
            String targetFormat) {
        // new AttachmentConvertTask(fileConvertor, attachment, file, targetFormat, attachmentRepoDao, imageRepoService)
        // .run();
        threadPool.submit(new AttachmentConvertTask(fileConvertor, attachment, file, targetFormat, attachmentRepoDao,
                imageRepoService));
    }

    static class AttachmentConvertTask implements Runnable {
        private FileConvertor fileconvertor;
        private BaseAttachmentRepo attachment;
        private File file;
        private String targetFormat;
        private BaseAttachmentRepoDao attachmentRepoDao;
        private BaseImageRepositoryService imageRepoService;

        public AttachmentConvertTask(FileConvertor fileconvertor, BaseAttachmentRepo attchment, File file,
                String targetFormat, BaseAttachmentRepoDao attachmentRepoDao,
                BaseImageRepositoryService imageRepoService) {
            this.fileconvertor = fileconvertor;
            this.attachment = attchment;
            this.file = file;
            this.targetFormat = targetFormat;
            this.attachmentRepoDao = attachmentRepoDao;
            this.imageRepoService = imageRepoService;
        }

        @Override
        public void run() {
            attachment.setConvertStartTime(new Date());
            attachment.setConvertState(FileConvertStates.PROGRESSING.getCode());
            attachmentRepoDao.save(attachment);

            String pdfPath = FilenameUtils.removeExtension(file.getAbsolutePath()) + "." + targetFormat;
            logger.info("convert task start:" + pdfPath);
            FileConvertResult convert = fileconvertor.convert(file, new File(pdfPath));
            attachment.setConvertEndTime(new Date());
            if (convert != null) {
                convertSuccess(attachment, convert);
            } else {
                convertFailed(attachment);
            }
        }

        private void convertFailed(BaseAttachmentRepo attchment2) {
            attchment2.setConvertState(FileConvertStates.FAILED.getCode());
            attchment2.setRetryCount(attchment2.getRetryCount()+1);
            attachmentRepoDao.save(attchment2);
        }

        private void convertSuccess(BaseAttachmentRepo a, FileConvertResult convert) {
            a.setConvertState(FileConvertStates.SUCCESS.getCode());
            a.setConvertFilePages(convert.getPages());
            a.setConvertFileSize(convert.getConvertFileSize());
            a.setConvertFormat(targetFormat);
            a.setConvertPath(FilenameUtils.removeExtension(attachment.getPath()) + "." + targetFormat);
            a.setCoverImgId(saveImageConver(convert.getCoverImageFile()));
            attachmentRepoDao.save(a);
        }

        public Long saveImageConver(File converImageFile) {
            if (converImageFile == null) {
                return null;
            }
            try {
                return imageRepoService.saveImage(converImageFile);
            } catch (IOException e) {
                logger.error("转换文件错误:" + converImageFile.getAbsolutePath(), e);
            }
            return null;
        }

    }

}
